#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Usage:
# alias check_backup='python3 <(curl -fsSL https://gitee.com/codesprite/gist/raw/master/check_backup.py)'
# check_backup <folder>


import os
import sys
import hashlib
import tarfile


# 获取文件 MD5
def get_md5(member, tar, buf_size=8192):
    md5_util = hashlib.md5()
    f = tar.extractfile(member)
    while True:
        data = f.read(buf_size)
        if not data:
            break
        md5_util.update(data)
    f.close()
    return md5_util.hexdigest()


# 获取字符串 MD5
def get_string_md5(text):
    md5_util = hashlib.md5()
    md5_util.update(text.encode('utf-8'))
    return md5_util.hexdigest()


def get_all_md5(parent, tree, tar):
    sum = ''
    total_size = 0
    files = list(tree.keys())
    files.sort()

    for f in files:
        path = os.path.join(parent, f)
        m = tree[f]
        if type(m) == tarfile.TarInfo:
            md5 = get_md5(m, tar)
            size = m.size
            print('%s|%s|%s|%d' % ('F', path, md5, size))
        else:
            md5, size = get_all_md5(path, m, tar)
        sum += md5
        total_size += size

    md5 = get_string_md5(sum)
    print('%s|%s|%s|%s' % ('D', parent, md5, total_size))
    return md5, total_size


def make_tree(tar):
    tree = {}

    def insert_file(node, path_arr, member):
        p = path_arr[0]
        if len(path_arr) == 1:
            if member.isdir():
                node[p] = {}
            else:
                node[p] = member
            return

        if p not in node:
            node[p] = {}

        insert_file(node[p], path_arr[1:], member)

    for m in tar.getmembers():
        insert_file(tree, m.name.split('/'), m)

    return tree


if __name__ == '__main__':
    package = sys.argv[1]
    tar = tarfile.open(package, 'r:*')
    tree = make_tree(tar)
    md5, size = get_all_md5('', tree, tar)
    print(md5)
    tar.close()
